#include "../common.h"
#include "baiscobj.h"
#include "BITMAP.H"
#include "QuadInterpolator.h"
#include "QuadState.h"


//////////////////////////////////////////////////////////////////////////
//
//
#define NUM_TEXTURE 7
//
#ifdef UNDER_CE
static void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,

                      GLfloat centerx, GLfloat centery, GLfloat centerz,

                      GLfloat upx, GLfloat upy, GLfloat upz)

{

    GLfloat m[16];

    GLfloat x[3], y[3], z[3];

    GLfloat mag;


    /* Make rotation matrix */

    /* Z vector */

    z[0] = eyex - centerx;

    z[1] = eyey - centery;

    z[2] = eyez - centerz;

    mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);

    if (mag)                     /* mpichler, 19950515 */
    {

        z[0] /= mag;

        z[1] /= mag;

        z[2] /= mag;

    }

    /* Y vector */

    y[0] = upx;

    y[1] = upy;

    y[2] = upz;

    /* X vector = Y cross Z */

    x[0] = y[1] * z[2] - y[2] * z[1];

    x[1] = -y[0] * z[2] + y[2] * z[0];

    x[2] = y[0] * z[1] - y[1] * z[0];

    /* Recompute Y = Z cross X */

    y[0] = z[1] * x[2] - z[2] * x[1];

    y[1] = -z[0] * x[2] + z[2] * x[0];

    y[2] = z[0] * x[1] - z[1] * x[0];

    /* mpichler, 19950515 */

    /* cross product gives area of parallelogram, which is < 1.0 for

    * non-perpendicular unit-length vectors; so normalize x, y here

    */

    mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);

    if (mag)
    {

        x[0] /= mag;

        x[1] /= mag;

        x[2] /= mag;

    }

    mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);

    if (mag)
    {

        y[0] /= mag;

        y[1] /= mag;

        y[2] /= mag;

    }

#define M(row,col)  m[col*4+row]

    M(0, 0) = x[0];

    M(0, 1) = x[1];

    M(0, 2) = x[2];

    M(0, 3) = 0.0;

    M(1, 0) = y[0];

    M(1, 1) = y[1];

    M(1, 2) = y[2];

    M(1, 3) = 0.0;

    M(2, 0) = z[0];

    M(2, 1) = z[1];

    M(2, 2) = z[2];

    M(2, 3) = 0.0;

    M(3, 0) = 0.0;

    M(3, 1) = 0.0;

    M(3, 2) = 0.0;

    M(3, 3) = 1.0;

#undef M

    glMultMatrixf(m);
    /* Translate Eye to Origin */
    glTranslatef(-eyex, -eyey, -eyez);
}

static void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear,  GLfloat zFar)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    double xmin, xmax, ymin, ymax;
    ymax = zNear * tan(fovy * PI / 360);
    ymin = -ymax;
    xmin = ymin * aspect;
    xmax = ymax * aspect;

    glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
    glMatrixMode(GL_MODELVIEW);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glDepthMask(GL_TRUE);
}


#endif  // UNDER_CE
//////////////////////////////////////////////////////////////////////
baiscobj::baiscobj()
{
    //
    m_pState = new CQuadPlayState(m_Quads);
    m_pIterp = new CQuadInterpolator(*m_pState);

    //camera
    g_eye[0] = 0;
    g_eye[1] = 0;
    g_eye[2] = DISTANCE_COVER + 5;
    g_Angle =  270;
    g_elev =   0;
    m_nDirection = 3;
    //
    m_cactus.resize(NUM_TEXTURE);

    for (int i = 0; i < NUM_TEXTURE; i++)
    {
        m_cactus[i].ID = 0;
        m_cactus[i].width = 0;
        m_cactus[i].height = 0;
    }

}

//
baiscobj::~baiscobj()
{
    delete m_pIterp;
    delete m_pState;
    m_pIterp = NULL;
    m_pState = NULL;


    for (int i = 0; i != m_Quads.size(); i++)
    {
        delete m_Quads[i];
    }

    m_Quads.clear();

    //
    for (int j = 0; j < NUM_TEXTURE; j++)
    {
        glDeleteTextures(1, &m_cactus[j].ID);
    }

    m_cactus.clear();
}

BOOL baiscobj::DisplayScene()
{
    float   rad_xz;
    float   speed = 0.1f;
    float   x = g_eye[0],
            y = g_eye[1],
            z = g_eye[2];

    rad_xz = float(3.13149 * g_Angle / 180.0f);
    g_eye[1] = 2;

    //
    g_look[0] = (float)(g_eye[0] + 200 * cos(rad_xz));
    g_look[2] = (float)(g_eye[2] + 200 * sin(rad_xz));
    g_look[1] = g_eye[1] + g_elev;

    gluLookAt(g_eye[0], g_eye[1], g_eye[2],
              g_look[0], g_look[1], g_look[2],
              0.0, 1.0, 0.0);
    return TRUE;
}

//bind texture
void baiscobj::BindTexture(UINT texturID)
{
    glBindTexture(GL_TEXTURE_2D, texturID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
}

//
void baiscobj::Update()
{
    //
    m_pIterp->update();
}

void baiscobj::init2()
{
    const int   iSum = 7;

    for (int i = 0; i < iSum; i++)
    {
        float size = 4.0f;
        float x = 0;
        float y = -size / 10;
        float z = 0;
        //
        int   cactus = i;
        float fAngle = 0;

        //
        CQuad3D* pQuad = new CQuad3D(i, size, size * 1.1f, CVector(x, y, z), fAngle, m_cactus[cactus].ID);
        m_pState->AddParticle(true, pQuad);
    }

    m_pState->m_offsetX = 0;
    m_pState->m_offsetZ = 0;

    m_pState->SetCenterParticle(iSum / 2);

    //
    m_pState->reset();
}

void baiscobj::play()
{
    if (m_nDirection == 0 && m_pState->m_leftSlides.size() > 0)
    {
        m_pIterp->start(m_pState->m_leftSlides[0]);
    }

    if (m_nDirection == 1 && m_pState->m_rightSlides.size() > 0)
    {
        m_pIterp->start(m_pState->m_rightSlides[0]);
    }

    m_nDirection = 3;
}

void baiscobj::SetDirection(int nDirection)
{
    m_nDirection = nDirection;
}

int baiscobj::click(int x, int y)
{
    return m_pState->click(x, y);
}